use diesel::PgConnection;
use crate::models::user::{User, ResUserInfo};
use crate::api::BusinessError;
use jsonwebtoken::{encode, Header, EncodingKey};
use std::env;
use chrono::{DateTime, Utc, TimeZone};
use crate::db_type::Role;
use diesel::result::Error;
use crate::models::CRUD;
use crate::models::user_info::UserInfo;


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Claims {
    pub exp: i64,
    pub uid: i32,
    pub school_id: i32,
    pub username: String,
    pub role: Role,
}

pub fn login(conn: &PgConnection, phone: String, password: String) -> Result<String, BusinessError> {
    match User::find_by_phone(conn, phone.clone()) {
        Ok(user) => {
            let claims = Claims {
                exp: 32503680000i64,
                uid: user.id,
                school_id: user.sid,
                username: user.username.clone(),
                role: if let Some(r) = user.role.clone() { Role::from(r) } else { Role::Guest },
            };

            let pwd = format!("{:x}", md5::compute(password));
            if user.phone == phone && user.password == pwd {
                let secret = env::var("TOKEN_SECRET")
                    .expect(".env 文件中 TOKEN_SECRET 没有设置");
                let token = encode(&Header::default(), &claims, &EncodingKey::from_secret(secret.as_ref()))
                    .expect("生成 token 出错");
                return Ok(token);
            }
            return Err(BusinessError::ValidationError { msg: "账号或密码不正确，请您检查后重试！".to_string() });
        }
        Err(e) => {
            match e {
                Error::NotFound => {
                    return Err(BusinessError::ValidationError { msg: "账号不存在，请您检查后重试！".to_string() });
                }
                _ => {
                    return Err(BusinessError::InternalError);
                }
            }
        }
    };
}

